#include "stdlib.hpp"
#include <purewell/purewell.hpp>
#include <purewell/buffer.hpp>

#include "bufferdeque.hpp"

namespace purewell
{

PWBufferDeque::PWBufferDeque()
{
}

PWBufferDeque::~PWBufferDeque()
{
}

ssize_t
PWBufferDeque::read(void* _buf, size_t blen) const
{
	const size_t rsize(std::min(blen, m_buf.size()));
	char* buf((char*)_buf);
	buffer_citr ib(m_buf.begin());
	buffer_citr ie(m_buf.begin()+rsize);

	while ( ib != ie )
	{
		*buf = *ib;
		++buf;
		++ib;
	}

	return (ssize_t)rsize;
}

ssize_t
PWBufferDeque::readAndSkip(void* _buf, size_t blen)
{
	char* buf((char*)_buf);
	const size_t rsize(std::min(blen, m_buf.size()));
	buffer_itr ib(m_buf.begin());
	buffer_itr ie(m_buf.begin()+rsize);

	while ( ib != ie )
	{
		*buf = *ib;
		++buf;
		++ib;
	}

	m_buf.erase(m_buf.begin(), m_buf.begin()+rsize);

	return (ssize_t)rsize;
}

ssize_t
PWBufferDeque::skip(size_t blen)
{
	const size_t rlen(std::min(blen,m_buf.size()));

	m_buf.erase(m_buf.begin(), m_buf.begin()+rlen);

	return (ssize_t)rlen;
}

ssize_t
PWBufferDeque::write(const void* _buf, size_t blen)
{
	const char* buf((const char*)_buf);
	const char* ib(buf);
	const char* ie(buf+blen);
	while ( ib != ie )
	{
		m_buf.push_back(*ib);
		++ib;
	}

	return (ssize_t)blen;
}

ssize_t
PWBufferDeque::readLine(void* _buf, size_t blen) const
{
	buffer_citr ib(m_buf.begin());
	buffer_citr ie(m_buf.end());
	size_t i(0);
	char* buf((char*)_buf);

	while ( ib != ie )
	{
		if ( '\n' == *ib )
		{
			++i;
			const size_t rlen(std::min(blen, i));
			if ( 0 > (size_t)read(_buf, rlen)) break;
			if ( blen > i ) buf[i-1] = 0x00;
			return i;
		}
		++ib;
		++i;
	}

	return (ssize_t)-1;
}

ssize_t
PWBufferDeque::readLineAndSkip(void* _buf, size_t blen)
{
	buffer_citr ib(m_buf.begin());
	buffer_citr ie(m_buf.end());
	size_t i(0);
	char* buf((char*)_buf);

	while ( ib != ie )
	{
		if ( '\n' == *ib )
		{
			++i;
			const size_t rlen(std::min(blen, i));
			if ( 0 > (size_t)readAndSkip(_buf, rlen)) break;
			if ( blen > i ) buf[i-1] = 0x00;
			return i;
		}
		++ib;
		++i;
	}

	return (ssize_t)-1;
}

};//namespace purewell

